local function onrandom_skill_level(self, level)
	local index = self.random_skill or self.inst.components.skilldata.random_skill or 0
	local skill = random_skill_data[index]
	if skill and skill.level_fn then
		skill.level_fn(self.inst, level)
	end
end

local function onskill(owner, skillid)
	if owner.components.skilldata then
		if owner.components.skilldata.skills then
			local skill = owner.components.skilldata.skills[skillid]
			if skill and 
				(skill.exclusive == nil or 
				skill.exclusive == owner.prefab or
				(type(skill.exclusive) == "table" and 
					table.contains(skill.exclusive, owner.prefab))) then
				if skill.effect_fn then
					skill:effect_fn(owner)
				end
			end
		end
	end
end

local function fixFirstMeta(self)
	if not self.effect_flag then
		onskill(self.inst, "random_skill")
	end
end

local onchangefn = {}
if skill_constant then
	for k, v in pairs(skill_constant) do
		if v.id then
			onchangefn[v.id] = function(self, val)
				onskill(self.inst, v.id)
				self.net_data[v.id]:set(val)
				self.effect_flag = true
			end
		end
	end
	onchangefn.random_skill_times = function(self, val)
		self.net_data.random_skill_times:set(val)
	end
	onchangefn.random_skill_level = function(self, val)
		onrandom_skill_level(self, val)
		self.net_data.random_skill_level:set(val)
	end
end

local SkillData = Class(function(self, inst) 
    self.inst = inst

    self.net_data = {
    	random_skill_times = net_byte(inst.GUID, "skilldata.random_skill_times", "random_skill_timesdirty"),
    	random_skill_level = net_int(inst.GUID, "skilldata.random_skill_level", "random_skill_leveldirty"),
    }
    self.skills = {}
    self:Init()

    self.coin_used = 0
    self.random_skill_times = 0
    self.random_skill_level = 0
    self.effect_flag = false

    if TheWorld.ismastersim and self.inst:HasTag("player") then
		self.inst:DoTaskInTime(.4, function() fixFirstMeta(self) end)
	end
end,
nil,
onchangefn)

function SkillData:Init()
	if skill_constant then
		local inst = self.inst
		for k, v in pairs(skill_constant) do
			local id = v.id
			local max_level = v.max_level or 1
			if max_level < 255 then 
				self.net_data[id] = net_byte(inst.GUID, "skilldata."..id, id.."skilldirty")
			elseif max_level < 32767 then
				self.net_data[id] = net_shortint(inst.GUID, "skilldata."..id, id.."skilldirty")
			else
				self.net_data[id] = net_int(inst.GUID, "skilldata."..id, id.."skilldirty")
			end
			self[id] = 0
			if TheWorld.ismastersim then
				self.skills[id] = v
				self.random_skill = math.random(#random_skill_data)
			end
		end
	end
end

function SkillData:InitRandomSkill(force)
	local age = self.inst.components.age:GetAgeInDays() or 0
    local playerlevel = self.inst.components.playerlevel.level or 1
    if force or (age < 2 and playerlevel < 2 and self.random_skill_times == 0) then
		--初始化随机天赋
		--先移除旧天赋
		if self.random_skill > 0 then
			random_skill_data[self.random_skill].uneffect(self.inst)
			self.random_skill_level = 0
		end
		self.random_skill = math.random(#random_skill_data)
		--random_skill_data[self.random_skill].effect(self.inst)
		self.random_skill_times = self.random_skill_times + 1
	end
	-- if self.random_skill > 0 then
	-- 	random_skill_data[self.random_skill].effect(self.inst)
	-- end
end

function SkillData:RandomSkillLevelUp()
	self.random_skill_level = self.random_skill_level + 1
end

function SkillData:GetLevel(id)
	if TheWorld.ismastersim then
		return self[id] or 0
	else
		return self.net_data[id]:value() or 0
	end
end

function SkillData:LevelUp(id, amount, book)
	if type(amount) ~= "number" then 
		book = amount == true 
		amount = 1 
	else
		book = book == true
	end
	if self[id] == nil or self.net_data[id] == nil then return end
	if TheWorld.ismastersim then
		if self.skills[id] then
			local skill = self.skills[id]
			local cost = skill.cost or 0
			local max_level = skill.max_level or 1
			if self[id] + amount > max_level then
				return false
			end
			if book then
				self[id] = self[id] + math.floor(amount)
				return true
			elseif self.inst.components.purchase then
				if self.inst.components.purchase.coin >= cost then
					self.inst.components.purchase:CoinDoDelta(-cost)
					self.coin_used = self.coin_used + cost
					self[id] = self[id] + math.floor(amount)
					return true
				end
			end
		end
	else
		--self.net_data[id]:set_local(self.net_data[id]:value() + math.floor(amount))
		SendModRPCToServer(MOD_RPC.RPG_skill.levelup, id, amount)
	end
end

function SkillData:SetLevel(id, level)
	if TheWorld.ismastersim then
		if self.skills[id] then
			local skill = self.skills[id]
			local max_level = skill.max_level or 1
			if level < 0 then
				level = 0
			end
			if level > max_level then
				level = max_level
			end
			if self[id] ~= math.floor(level) then
				self[id] = math.floor(level)
			end
		end
	end
end

function SkillData:OnSave()
	local data = {}
	if skill_constant then
		for k, v in pairs(skill_constant) do
			if v.id then
				data[v.id] = self[v.id] or 0
			end
		end
	end
	data.coin_used = self.coin_used or 0
	data.random_skill_times = self.random_skill_times or 0
	data.random_skill_level = self.random_skill_level or 0
	return data
end

function SkillData:OnLoad(data)
	for k, v in pairs(data) do
		self[k] = v or 0
	end	
	--self:InitRandomSkill()
end

return SkillData